home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-10-25 | 32.1 KB | 1,165 lines |
-
- ;write leading stem to screen
-
- write_stem:
- mov al,'║' ;load stem character
- a1:
- call cursor ;position cursor
- call write_chr ;write stem character to screen
- inc dh ;increment row
- loop a1 ;decrement loop count
- ret ;exit
-
- ;write stem character and route/subchart indicators to screen
-
- write_indicator:
- mov dx,w cursor_pos ;load cursor coordinates
- inc b cursor_pos+1 ;increment row
- call cursor ;position cursor
- mov si,o indicator ;load offset to string
- a1:
- lodsb ;read character from string
- or al,al ;end of string?
- je ret ;exit if it is
- call write_chr ;write character to screen
- jmp a1 ;read next character
-
- ;get inverse sign in ax
-
- inv_sgn:
- or ax,ax ;is value zero?
- je >a1 ;exit with one in ax if it is
- xor ax,ax ;load zero
- ret ;exit
- a1:
- mov ax,1 ;load one
- ret ;exit
-
- ;get sign in ax
-
- sgn:
- or ax,ax ;is value zero?
- je ret ;exit with one in ax if it is
- mov ax,1 ;load one
- ret ;exit
-
- ;copy current box routes
-
- get_current_routes:
- push ax ;save register
- mov ax,bp ;load current box
- jmp >a1 ;copy its routes
-
- ;copy routes from box to routes store
-
- get_routes:
- push ax ;save register
- a1:
- push cx,dx,si,di,ds,es ;save registers
- mov dx,ax ;save box
- call get_box ;get box pointer
- mov si,di ;copy offset
- mov ds,ax,es ;copy segment
- mov es,ax,cs ;copy code segment
- mov di,o routes ;load offset to routes store
- movsw ;copy neighbour box
-
- ;copy routes data
-
- lodsw ;load yes route
- cmp ax,dx ;is it a outstanding route?
- if e xor ax,ax ;clear route
- stosw ;store route
- lodsw ;load no route
- cmp ax,dx ;is it a outstanding route?
- if e mov ax,1 ;flag decision box if it is
- stosw ;store route
-
- ;copy subchart markers
-
- movsw ;copy child chart pointer
- movsw ;copy parent box pointer
- pull es,ds,di,si,dx,cx,ax ;restore registers
- ret ;exit
-
- ;get total real routes from current box
-
- get_current_real_routes:
- mov ax,bp ;load current box
- call get_routes ;copy routes from box to store
- push ax,bx,cx,si ;save registers
- mov si,no ;load offset to routes data
- mov w real_routes,0 ;clear real routes count
-
- ;get real routes count
-
- a1:
- mov ax,w[si+routes] ;load box from route
- cmp ax,first_box ;is there a route?
- jbe >a2 ;decrement loop count if not
- inc w real_routes ;increment count
- mov w first_route,si ;save route
-
- ;move to next route
-
- a2:
- sub si,2 ;move down a route
- jne a1 ;decrement loop count
- pull si,cx,bx,ax ;restore registers
- ret ;exit
-
- ;position cursor for command line
-
- write_command_line:
- push cx,si ;save option string length
- mov cx,di ;load offset to end of string
- sub cx,o command_line ;calculate length of string
- jcxz >b1 ;exit if command line is empty
- mov dl,80 ;load maximum screen width
- sub dl,cl ;subtract line length from it
- shr dl,1 ;calculate column
- mov dh,b cursor_pos+1 ;load row
- inc b cursor_pos+1 ;increment row
-
- ;position cursor and load offset to start of options
-
- call cursor ;position cursor
- mov si,o command_line ;load offset to string
- mov di,si ;clear string
-
- ;load and write character to screen
-
- a1:
- mov dl,novid ;store normal video attribute
- cmp w[si-2],' .' ;is it option character
- if e mov dl,revid ;load reverse video attribute if it is
- mov b attribute,dl ;store attribute
- lodsb ;load character from string
- call write_chr ;write it to screen
- loop a1 ;decrement loop count
- b1:
- pull si,cx ;restore option string offset and count
- ret ;exit
-
- ;clear bottom lines
-
- clear_line:
- mov dx,01700h ;load cursor coordinates
- mov al,' ' ;load space character
- cs mov bh,active_page ;load current video page
- mov bl,novid ;load attribute
- call >a1 ;clear last but one line
- mov dx,01800h ;load cursor coordinates
-
- ;clear line
-
- a1:
- push cx ;save register
- call cursor ;position cursor
- mov cx,80 ;load line count
- a1:
- call write_chr ;clear row
- loop a1 ;decrement loop count
- pull cx ;restore register
- ret ;exit
-
- ;clear options array
-
- clear_options:
- mov cx,option_count+2 ;load option count
- mov di,o option_array ;load offset to array
- mov es,ax,cs ;copy code segment
- xor ax,ax ;clear register
- rep
- stosw ;clear options array
- ret ;exit
-
- ;write current non-attached route to stem
-
- write_route_stem:
- mov al,'(' ;write route marker to stem string
- shr bx,1 ;calculate offset to key
- add bx,5
- mov ah,b[bx+keys] ;load key option
- mov w route_string,ax
- mov al,')' ;load close bracket
- mov b route_string+2,al ;store it
- ret ;exit
-
- ;set variables for route selection
-
- set_mode_2:
- mov w insert_mode,2 ;set mode
- mov bx,w current_route ;load current route
- call write_route_stem ;put it in stem string
- mov b chart_flag,1 ;set chart entry flag
- stc ;exit to chart loop
- ret
-
- ;check if any routes left in box
-
- check_decision_flag:
- mov w branch_route_count,0 ;clear flag
- cmp w current_route,0 ;is box decision box?
- je >a1 ;check insert mode flag if not
- mov ax,bp ;load current box
- call get_box ;get box pointer
- es cmp w[di+no],0 ;is neither route set?
- jne >a1 ;check insert mode if not
- es mov w[di+no],1 ;indicate box is decision box
-
- ;check if insert mode is on
-
- a1:
- mov ax,w insert_mode ;load insert flag
- or ax,ax ;is it?
- je >b1 ;set chart entry flag if not
- call make_insert_box_child ;check if old box is child of subchart
- mov b chart_flag,3 ;set chart entry flag
- stc ;exit to start of chart loop
- ret ;exit
-
- ;set chart entry flag and exit
-
- b1:
- mov ax,w temp2 ;load flag
- cmp ax,3 ;prompt for descripter string?
- je >a1 ;set chart entry flag if yes
- mov b chart_flag,al ;set chart entry flag
- stc ;exit to chart
- ret
-
- ;set chart entry flag and exit
-
- a1:
- mov b chart_flag,2 ;set chart entry flag
- mov b box_made,0 ;dont prompt for new box
- stc ;exit to chart
- ret
-
- ;link option
-
- link_option:
- mov b new_chart,0 ;indicate chart changed
- mov bx,w route ;load current route offset
- cmp w key_option,1*2 ;is key option link?
- if e jmp long >c1 ;link subchart if it is
- cmp w insert_mode,0 ;are any boxes being inserted?
- je >b1 ;check for subchart if not
- xchg bp,w box_save ;restore current box
- mov w first_route,bx ;store current route offset
-
- ;check if subchart is being copied
-
- b1:
- cmp w box_to_subchart,0 ;is it?
- jne >a1 ;link it to neighbour boxes if it is
-
- ;link inserted box to current box
-
- mov ax,w box_save ;load inserted box
- mov dx,bp ;load new box
- call store_box_par ;write it to current route
- mov w temp2,4 ;set flag
-
- ;restore current box and exit to chart loop
-
- mov si,bp ;load box after inserted box
- xor bp,bp ;load zero
- mov w message,bp ;clear message buffer
- xchg bp,w box_save ;restore current box
- jmp check_decision_flag ;check decision flag and exit
-
- ;link subchart to neighbour boxes
-
- a1:
- mov ax,w box_to_subchart ;load subchart leading neighbour box
- mov si,ax ;save it
- mov dx,w next_box ;load new box
- cmp ax,-1 ;is there a neighbour box?
- jne >a1 ;link it if there is
- mov ax,w subchart_link ;load box to link subchart to
- inc si ;clear leading neighbour route
- jmp >a2 ;link it to subchart
-
- ;link route of leading neighbour box to new box
-
- a1:
- call get_box ;get its pointer
- mov bx,w route_to_subchart ;load its route
- es mov ax,w[di+bx] ;load box that it points to
- es mov w[di+bx],dx ;point leading box to subchart
- a2:
- xor bx,bx ;load previous route offset
- call store_box_par ;link subchart to following box
-
- ;create new box
-
- mov w route,ax ;save following box
- call make_box ;create new box
- es mov w[di],si ;store leading neighbour box
- mov bx,child ;load element offset
- call get_current_box_par ;get first box in subchart
- es mov w[di+bx],ax ;point new box to it
-
- ;copy descripter pointer
-
- mov bx,descripter_length ;load offset to descripter pointer
- a1:
- call get_current_box_par ;get parameter
- es mov w[di+bx],ax ;copy it
- add w start_free_memory,ax ;raise ram top
- adc w start_free_memory+2,0
-
- ;copy descripter string
-
- es mov ax,w[di+descripter] ;copy address
- es mov dx,w[di+descripter+2]
- push di,es ;save pointer to new box
- call get_pointer ;get destination pointer
- mov ax,bp ;load subchart
- call get_box_descripter ;get its descripter pointer
- rep
- movsb ;copy descripter string
- mov ds,ax,cs ;restore data segment register
- pull es,di ;restore pointer to new box
-
- ;copy parent of leading neighbour box to new box
-
- mov ax,w subchart_link ;load following neighbour box
- mov bx,parent ;load offset to element
- call get_box_par ;get parent of neighbour box
- es mov w[di+bx],ax ;store it in new box
-
- ;copy routes of subchart to new box
-
- mov bx,no ;load offset to route element
- xor si,si ;clear route count
- xor dx,dx ;clear first route
-
- ;check if route exists in subchart
-
- a1:
- mov w[si+option_routes],0 ;clear extra route
- call get_current_box_par ;get route
- or ax,ax ;is there one?
- je >a2 ;decrement loop count if not
- cmp ax,1 ;is it decision box marker?
- je >a3 ;store it if it is
-
- ;indicate route exists but points to nowhere
-
- mov ax,w next_box ;copy next box
- mov dx,bx ;save route
- inc si ;increment route count
- mov w[bx+option_routes],1 ;indicate route is available option
- a3:
- es mov w[di+bx],ax
- a2:
- sub bx,2 ;move to next route
- jne a1 ;decrement loop count
- mov bp,w next_box ;load copied subchart
- mov bx,dx ;load route offset
- cmp si,1 ;is there more than one route?
- je >c1 ;link new box to route box if not
-
- ;prompt for route from subchart
-
- mov w key_option,1*2 ;store key option
- mov w box_save,1 ;set flag
- mov w current_route,bx ;store first route
- call write_message ;write bottom line prompt to buffer
- db 'Select which route from subchart to link',0
- jmp set_mode_2 ;set mode and exit to chart loop
-
- ;point route from subchart to following neighbour box
-
- c1:
- mov dx,w subchart_link ;copy following box to new box route
- call store_current_box_par ;point subchart route to following box
- xor ax,ax ;load zero
- mov w key_option,ax ;clear key option
- mov w box_save,ax ;clear flag
- mov w insert_mode,ax ;clear mode
- mov w box_to_subchart,ax ;clear box to subchart
- mov b message,al ;clear message buffer
- mov b chart_flag,2 ;set flag
- mov b box_made,al ;indicate box created
-
- ;check if box after inserted box is child box of subchart
-
- xchg w subchart_link,ax ;clear subchart follow box
- mov si,ax ;load new child box
- mov dx,first_box-1 ;new box marker hasnt been incremented
- call make_insert_box_child2 ;check for any references to old box
- stc ;exit to start of chart loop
- ret
-
- ;check if sufficient memory
-
- check_memory:
- push ax,dx ;save registers
- call get_available_memory ;get memory available
- jc >e1 ;exit if overflow
- or dx,dx ;is there plenty available memory?
- jne >a1 ;create box if there is
- cmp ax,box_record+128 ;is there enough memory for new box
- jae >a1 ;exit if there is
-
- ;exit
-
- e1:
- pull dx,ax ;restore registers
- jmp memory_error ;exit if not
- a1:
- pull dx,ax ;restore registers
- ret ;exit
-
- ;check if option is 'create' or 'cancel'
-
- create_box:
- mov ax,w box_save ;load flag
- or ax,ax ;is option 'create'?
- je >b1 ;create box if it is
- mov bp,ax ;restore main box
- xor ax,ax ;clear register
- mov w box_save,ax ;clear main box save store
- mov w box_to_subchart,ax ;clear flag
- mov w key_option,ax ;clear key option store
- mov b message,al ;clear bottom line message buffer
- mov b chart_flag,4 ;store flowchart entry flag
- stc ;exit to start of chart loop
- ret ;exit
-
- ;check if sufficient memory for new box
-
- b1:
- mov bx,w route ;load current route
- mov dx,w next_box ;load next available box
- call store_current_box_par ;point current route to new box
- mov w temp2,2 ;prompt for descripter string
- jmp check_decision_flag ;set decision flag if decision box
-
- ;save current box
-
- branch:
- mov w box_save,bp ;save current box
- mov w link_box,bp ;store current box as link box
- call write_message ;write branch message to message buffer
- db 'Choose box to branch to',0
- mov b chart_flag,1 ;store chart entry flag
- stc ;exit to chart loop
- ret
-
- ;renumber chart
-
- renumber:
- mov w temp3,bp ;save current box
- a1:
- call move_to_first_box ;move to first box in chart
- mov bx,parent ;load parent route offset
- call get_current_box_par ;get parent of this chart
- or ax,ax ;top level?
- je >a2 ;initialise box counter if it is
-
- ;move to next chart up
-
- mov bp,ax ;load box of parent chart
- jmp a1 ;move to start of next chart if not
- a2:
- mov w temp2,first_box ;store first box number
- mov w temp1,sp ;save stack pointer
-
- ;if box is current box note new id
-
- b1:
- mov dx,w temp2 ;load new box number
- or dh,080h ;indicate current box redirected
- cmp bp,w temp3 ;is this box current box?
- if e mov w temp3,dx ;mark new box number
-
- ;check bookmarks
-
- mov cx,10 ;load bookmark count
- mov si,o bookmarks-2 ;load offset to bookmarks
- a1:
- inc si,si ;move to next bookmark
- cmp w[si],bp ;is current box a bookmark?
- if e mov w[si],dx ;redirect it if it is
- loop a1 ;decrement loop count
- and dx,07fffh ;load new box number
- mov bx,box_temp ;load offset to box temporary store
- call store_current_box_par ;store boxes new number/offset
-
- ;check for subchart
-
- call get_current_routes ;get total real routes
- mov ax,w routes+child ;load child element
- or ax,ax ;is there one?
- je >a1 ;push any fixed routes if not
- push ax ;save subchart on stack
- mov bx,parent ;get parent of subchart
- call get_box_par
- cmp ax,bp ;is current box a step parent?
- if ne pull ax ;clear subchart from stack
-
- ;push any fixed routes onto stack
-
- a1:
- mov si,no ;load offset to no route
- xor bx,bx ;load previous route offset
- a1:
- mov ax,w[si+routes] ;load route
- cmp ax,first_box ;is it a box route?
- jb >a2 ;move to next route if not
-
- ;check if route is unique
-
- cmp ax,w[si+routes+2] ;is this route same as 'no' route?
- je >a2 ;ignore this route if it is
- push ax ;save box route
- call get_box_par ;get previous route of box route
- cmp ax,bp ;does it point to current box?
- if ne pull ax ;clear box from stack
- a2:
- sub si,2 ;move to next route
- jne a1 ;check next route if not finished
-
- ;check if any more boxes on stack
-
- or dh,080h ;set high bit in number
- call check_references ;replace all references with new box
- cmp sp,w temp1 ;is there?
- je >a1 ;reorder flowchart if not
- pull bp ;load next current box
- inc w temp2 ;move to new box number
- jmp b1 ;check for any references to current box
-
- ;sort boxes
-
- a1:
- inc w temp2 ;increment last box stored
- mov ax,w next_box ;calculate number of boxes to sort -1
- sub ax,first_box+1
- je >c1 ;check if any blank boxes if just one
- mov w temp1,ax
-
- ;get pointer to start of chart
-
- b1:
- mov cx,temp1 ;load box count
- mov ax,first_box ;load first box parameter
- call get_box ;get pointer to it
- mov si,di ;copy it
- add si,box_record ;point ds:si to next box record
- mov ds,ax,es ;copy segment
- xor dx,dx ;clear swap flag
-
- ;swap box records if second box number/offset is lower than first
-
- b2:
- mov ax,w[si+box_temp] ;load box number/offset of second box
- es cmp ax,w[di+box_temp] ;is its new position before first box?
- ja >b3 ;move to next
- mov bx,box_temp ;load top element in record
- or dx,bx ;indicate swap taken place
-
- ;swap records
-
- a1:
- mov ax,w[si+bx] ;load second box parameter
- es xchg ax,w[di+bx] ;exchange it with first box
- mov w[si+bx],ax
- sub bx,2 ;move to next element
- jnc a1 ;exchange next element if no borrow
-
- ;move to next box record
-
- b3:
- call add_record2 ;move to next record
- loop b2 ;decrement middle loop count
- mov ds,ax,cs ;restore data segment register
- or dx,dx ;any swaps?
- je >c1 ;check if any empty boxes if not
- dec w temp1 ;are boxes sorted?
- jne b1 ;sort again if not
-
- ;delete any blank boxes
-
- c1:
- mov ax,w next_box ;load next new box
- cmp ax,w temp2 ;are there any blank boxes?
- je >b1 ;exit if not
-
- ;calculate size of block to move
-
- mov bx,w start_free_memory ;copy top of data address
- mov w shift_count,bx
- mov bx,w start_free_memory+2
- mov w shift_count+2,bx
- call get_box_address ;get source address
- sub w shift_count,ax ;calculate size of block
- sbb w shift_count+2,dx
- push ax,dx ;save it
- mov bx,ax
- mov cx,dx
- call get_pointer ;convert it to pointer format
- mov si,di ;copy it to source pointer
-
- ;get destination pointer
-
- mov ax,w temp2 ;load destination box number
- mov w next_box,ax
- call get_box_address ;get destination address
- mov bp,es ;copy source segment
- mov ds,bp
- call get_pointer ;convert destination address to pointer
- sub ax,bx ;calculate correction
- sbb dx,cx
- push ax,dx ;save it
- call shift_down ;shift descripter strings
- mov ds,ax,cs ;restore data segment register
-
- ;update box descripter addresses
-
- pull si,bx,dx,ax ;restore correction and address
- call update_descripters ;update descripter addresses
-
- ;clear high bits from route/parent/child pointers
-
- b1:
- mov ax,first_box ;get pointer to first box
- call get_box
- mov cx,w next_box ;calculate number of boxes
- sub cx,ax
- a1:
- mov bx,parent ;load top element
-
- ;strip bit 15 in each route
-
- a2:
- es and w[di+bx],07fffh ;get rid of high bit
- sub bx,2 ;decrement inner loop count
- jnc a2
- call add_record ;move to next box
- loop a1 ;decrement outer loop count
-
- ;restore bookmarks
-
- mov ax,07fffh ;clear high bits of each bookmark
- mov si,o bookmarks ;load offset to bookmarks
- mov cx,10
- a1:
- and w[si],ax ;clear high bit of bookmark
- inc si,si ;move to next bookmark
- loop a1 ;decrement loop count
-
- ;make current box first box and exit
-
- mov w sub_stack,top_stack ;reset subchart stack
- mov bp,w temp3 ;load first box
- and bp,ax
- mov b chart_flag,1 ;set chart entry flag
- stc ;exit to start of chart loop
- ret
-
- ;reset chart flags
-
- reset_chart_flags_lo:
- mov ax,first_box ;load first box number
- call get_box ;get pointer to it
- mov cx,w next_box ;calculate box count
- sub cx,ax
- a1:
- es mov b[di+box_temp],-1 ;clear flag
- call add_record ;move to next box
- loop a1 ;decrement loop count
- ret ;exit
-
- ;reset chart flags
-
- reset_chart_flags_hi:
- mov ax,first_box ;load first box number
- call get_box ;get pointer to it
- mov cx,w next_box ;calculate box count
- sub cx,ax
- a1:
- es mov b[di+box_temp+1],-1 ;clear flag
- call add_record ;move to next box
- loop a1 ;decrement loop count
- ret ;exit
-
- ;move to first box in chart
-
- move_to_first_box:
- call reset_chart_flags_lo ;flag all boxes unchecked
- xor bx,bx ;load offset to leading box route
- mov ax,bp ;load current box
-
- ;check if box is first in chart/sub-chart
-
- mov bx,parent ;load offset to parent route
- call get_box_par ;get parent box of current chart
- mov dx,ax
- mov ax,first_box ;load id of first box in chart
- call get_box ;get pointer to it
- mov cx,w next_box ;calulate number of boxes
- sub cx,ax
- jmp >a2 ;don't move pointer
-
- ;get first box in chart id
-
- a1:
- inc ax ;increment box marker
- call add_record ;move to next box record
- a2:
- es cmp w[di+bx],dx ;is this box target parent chart box?
- if e es cmp w[di],0 ;is this first box in its chart?
- loopne a1 ;move to next box if not
-
- ;check if at start of chart
-
- mov w temp1+2,ax ;store first box id
- mov ax,bp ;load current box
- c1:
- mov bp,ax ;save box id
- mov dx,w temp1+2 ;load first box id
- sub dx,bp ;first box in chart?
- je ret ;exit if it is
-
- ;check if box has been marked
-
- xor bx,bx ;load offset to previous route
- call get_box_par ;get leading neighbour box
- mov si,ax ;save id of marked box
- mov bx,box_temp ;load offset to flag
- call get_box_par ;get flag
- or al,al ;has this box been checked?
- je >c2 ;find alternative route to it if it has
-
- ;mark this box and move to next leading neighbour box
-
- mov ax,si ;load neighbour box id
- mov bx,box_temp ;load offset to flag
- mov dx,0ff00h ;mark this box
- call store_box_par ;get flag
- jmp c1 ;check next box
-
- ;find link from start of chart to current box
-
- c2:
- call reset_chart_flags_hi ;flag all boxes unchecked
- mov ax,w temp1+2 ;load first box in this chart
- mov dx,bp,si ;load box to find reference to
- call find_box_to_box ;check if alternative route to box
- jc >a1 ;move to next box in chain if not found
-
- ;redirect neighbour box
-
- xor bx,bx ;load offset to neighbour box route
- mov dx,si ;load box linked from start of chart
- call store_current_box_par ;redirect current box to linked box
- a1:
- mov ax,bp ;load current box
- jmp c1 ;move to neighbour box
-
- ;check if box is standalone in a sub-chart
-
- b2:
- es cmp w[di+previous],first_box ;is box at head of chart/sub-chart?
- jae >b3 ;check routes if not
- es mov ax,w[di+child] ;is box parent to subchart?
- es mov bx,w[di+parent] ;save parent box
- call get_box ;get box pointer
- es cmp bp,w[di+parent] ;is child maternal chart?
- jne >b3 ;exit with error if not
-
- ;check if parent box is maternal
-
- xchg ax,bx ;copy parent box
- call get_box ;get box pointer
- es cmp bp,w[di+child] ;is box maternal parent?
- jne >b3 ;exit with error if not
- es mov w[di+child],bx ;link current box parent to box child
- call get_current_box ;copy routes for current box
- xor bx,bx ;load zero
- es xchg bx,w[di+parent] ;load parent of current box
-
- ;redirect all parent chart references to parent of current box
-
- mov ax,first_box ;load first box number
- call get_box ;get pointer to it
- mov cx,w next_box ;calculate box count
- sub cx,ax
- a1:
- es cmp w[di+parent],bp ;is box child to current box?
- if e es mov w[di+parent],bx ;redirect it to current box if it is
- call add_record ;move to next box
- loop a1 ;decrement loop count
-
- ;make first box in child subchart current box
-
- call get_current_box ;get pointer to current box
- es mov bp,w[di+child] ;make current box child box
- es mov w[di],-1 ;indicate box deleted
- es mov w[di+box_temp],-1 ;make sure this box will end up at the
- mov b new_chart,0 ;indicate chart changed
- mov b chart_flag,4 ;set chart entry flag
- stc ;exit to chart loop
- ret
-
- ;delete current box
-
- delete_box:
- call get_current_box ;copy routes for current box
- cmp w real_routes,1 ;is there more than 1 route
- je >b1 ;delete box if not
- jb b2 ;check routes if not
-
- ;check if deleting route will split chart up
-
- b3:
- mov bx,no ;check if no, no route will split chart
- a1:
- call store_save_route ;save and clear route
- jb >a2 ;check yes route if it doesn't go to box
- push bx,bp ;save route offset
- mov w route,bx ;store route to be checked
- call will_box_be_missed ;will deleted box split up chart?
- pull bp,bx ;restore route offset
- jc ret ;exit if chart will be split up
- call store_current_box_par ;restore route in dx to current box
- a2:
- dec bx,bx ;move to next route
- jne a1 ;check it out
-
- ;check if current box is at start of chart
-
- b1:
- xor bx,bx ;load neighbour box offset
- call get_current_box_par ;get current box routes
- mov w temp1,ax ;save it
- or ax,ax ;is there one?
- je >c1 ;delete box if not
- mov dx,ax ;save box of neighbour route
- call get_routes ;get its routes
- xor bx,bx ;start with yes route
-
- ;move to neighbour box joining route
-
- a1:
- add bx,2 ;move to next route
- cmp w[bx+routes],bp ;is neighbour box route joining route?
- jne a1 ;check next route if not
- mov w route_select,bx ;save route
-
- ;get following neighbour box
-
- mov bx,w first_route ;load fixed route element
- call get_current_box_par ;get box of current box
- cmp ax,w temp1 ;is it a outstanding route?
- if e xor ax,ax ;clear route
-
- ;check if previous neighbour box is decision box
-
- mov bx,w route_select ;load leading neighbour box route
- cmp bx,no ;is neighbour route 'no'?
- jb >a1 ;check for any branches if not
- cmp w routes+yes,0 ;is there a yes or no route?
- je >a1 ;check for any branches if not
- cmp w routes+no,0 ;is box decision box?
- je >a1 ;check for branches if not
-
- ;check if box will point to itself
-
- cmp ax,dx ;will box point to itself?
- if e xor ax,ax ;clear route if it will
- or ax,ax ;will route be linked to trailing box
- if e inc ax ;flag empty route if not
- jmp >a2 ;store box parameter
-
- ;check if route from current box is fixed route
-
- a1:
- or bx,bx ;is there a route?
- jne >a2 ;line it if there is
- cmp ax,first_box ;is route to box?
- if b xor ax,ax ;clear route if not
- a2:
- xchg ax,dx ;exchange neighbour boxes
- mov bx,w route_select ;load route from neighbour box
- call store_box_par ;point previous box to following box
-
- ;delete current box
-
- c1:
- call get_current_box ;get pointer to current box
- es mov w[di],-1 ;indicate box deleted
- es mov w[di+box_temp],-1 ;make sure this box will end up at the
- ;end of box block when renumbering
- mov b new_chart,0 ;indicate chart changed
-
- ;delete descripter string
-
- mov bx,w start_free_memory ;calculate size of text block to move
- mov cx,w start_free_memory+2
- es mov ax,w[di+descripter] ;load address to descripter string
- es mov dx,w[di+descripter+2]
- sub bx,ax
- sbb cx,dx
- es mov si,w[di+descripter_length]
- sub bx,si
- sbb cx,0
- mov w shift_count,bx ;save size of block
- mov w shift_count+2,cx
-
- ;get source and destination pointers
-
- call get_pointer ;convert address to pointer
- add ax,si ;add string size to address
- adc dx,0
- push ax,dx,si ;save address
- push di,es ;save pointer
- call get_pointer ;get source pointer
- mov si,di
- mov ds,ax,es
- pull es,di ;restore destination pointer
- call shift_down ;delete descripter string
- mov ds,ax,cs ;restore data segment register
-
- ;update descripter addresses of other boxes
-
- pull ax ;restore descripter size
- neg ax ;make count minus
- cwd
- mov bx,ax ;save it
- mov si,dx
- pull dx,ax ;restore address
- call update_descripters ;update descripter addresses
-
- ;make current box following neighbour box
-
- mov w sub_stack,top_stack ;clear subchart stack
- mov dx,w temp1 ;load leading neighbour box
- mov bx,w first_route ;load route offset
- call get_current_box_par ;get following neighbour box
- cmp dx,ax ;will box point to itself?
- if e xor ax,ax ;clear box reference if it will
- push ax ;make it current box
-
- ;redirect trailing neighbour box
-
- cmp ax,first_box ;is there a route
- jb >a1 ;exit if not
- call get_box ;get pointer to box
- es cmp w[di],0 ;is box first in chart?
- if ne es mov w[di],dx ;change its leading neighbour box if not
-
- ;clear any other references to current box
-
- xor ax,ax ;assume no yes route
- es cmp w[di+yes],bp ;does route point to current box?
- if e es mov w[di+yes],ax ;clear route if it does
- es cmp w[di+no],bp ;does route point to current box?
- jne >a1 ;update remaining boxes if not
- es cmp w[di+yes],ax ;is there a yes route?
- if ne inc ax ;indicate box is decision box it yes
- es mov w[di+no],ax ;clear route if it does
-
- ;check if there are any references to deleted box
-
- a1:
- pull dx ;load new box route
- call check_references ;delete all references to current box
- cmp dx,first_box ;is route from current box terminator
- if b mov dx,w temp1 ;load leading neighbour box if it is
- mov si,bp ;load old box
- cmp w real_routes,0 ;is there a fixed route?
- je >b1 ;check if leading neighbour box if not
- mov bp,dx ;load new box route
-
- ;check if deleted box is at the start of a subchart
-
- or dx,dx ;is there a leading neighbour box?
- jne >a1 ;exit to chart loop if there is
- mov ax,si ;load deleted box
- mov bx,parent ;load offset to parent element
- call get_box_par ;get deleted boxes parent
- or ax,ax ;is there one?
- jne >c1 ;check if any step parents if there is
- a1:
- mov b chart_flag,4 ;store chart entry flag
- stc ;exit to start of chart loop
- ret
-
- ;check if any boxes left
-
- b1:
- or dx,dx ;is there a leading neighbour box?
- jne >b1 ;make it current box if there is
- mov bx,parent ;load parent element offset
- call get_current_box_par ;get parent of deleted box
- or ax,ax ;is there one?
- jne >a1 ;make it current box if there is
- xor bp,bp ;indicate exit to menu and clear chart
- ret
-
- ;make parent box of deleted box current box
-
- a1:
- mov bp,ax ;make parent box current box
- mov bx,child ;load child element offset
- call get_current_box_par ;get child subchart of parent
- mov si,ax ;save it
- jmp >c2 ;clear all references to subchart
-
- ;make leading box current box
-
- b1:
- mov bp,dx ;load leading box
- mov b chart_flag,4 ;set chart loop entry flag
- stc ;exit to chart loop
- ret
-
- ;exit to chart loop
-
- c1:
- call make_insert_box_child ;check if old box is child of subchart
- mov b chart_flag,4 ;set chart entry flag
- stc ;exit to chart loop
- ret
-
- ;clear all references to deleted subchart
-
- c2:
- mov ax,first_box ;load first box number
- call get_box ;get its pointer
- mov bx,child ;load child box element offset
- mov cx,w next_box ;calculate box count
- sub cx,ax
-
- ;check child of box
-
- a1:
- es cmp w[di+bx],si ;is it a step parent of deleted subchart
- jne >a2 ;decrement loop count if not
- es mov w[di+bx],0 ;cnear child status
- a2:
- call add_record ;increment box
- loop a1 ;decrement loop count
-
- ;exit to chart loop
-
- mov b chart_flag,4 ;set chart entry flag
- stc ;exit to chart loop
- ret
-
- ;check if old box is child box of subchart
-
- make_insert_box_child:
- mov dx,first_box ;load first box
- mov ax,si ;load old box
- make_insert_box_child2:
- mov bx,parent ;load offset to parent element
- call get_box_par ;get parent box
- or ax,ax ;is there a parent?
- je ret ;exit if not
- mov ax,first_box ;load first box number
- call get_box ;get its pointer
- mov bx,child ;load child box element offset
- mov cx,w next_box ;calculate box count
- sub cx,dx
-
- ;get box pointer and check its child status
-
- a1:
- es cmp w[di+bx],si ;does it point to deleted box
- jne >a2 ;decrement loop count if not
- es mov w[di+bx],bp ;store new current box as child box
- a2:
- call add_record ;increment box
- loop a1 ;decrement loop count
- ret ;exit
-
- ;replace any references to current box with dx
-
- check_references:
- mov ax,first_box ;load first box number
- call get_box ;get pointer to it
- mov cx,w next_box ;calculate box count
- sub cx,ax
- a1:
- es cmp w[di],-1 ;is box deleted?
- if ne call check_routes ;check if any routes point to box
- call add_record ;move to next box
- loop a1 ;decrement loop count
- ret ;exit
-
- ;check if any routes point to current box
-
- check_routes:
- push cx ;save register
- xor si,si ;clear existing routes marker
- mov cx,1 ;load loop count
- mov bx,yes ;load yes route offset
- es cmp w[di+no],0 ;is box decision box?
- if ne inc cx ;load loop count
-
- ;check if route points to current box
-
- b1:
- es mov ax,w[di+bx] ;load route
- or ax,ax ;is route active?
- je >b2 ;decrement loop count if not
- add ax,si ;add existing route marker to route
- cmp ax,1 ;is route void?
- jne >a1 ;check if it points to current box if no
- or dx,dx ;is reference deleted box?
- jne >b3 ;check parent and child pointers if not
- es mov w[di+bx],0 ;clear route
- pull cx ;restore register
- ret ;exit
-
- ;check if route points to current box
-
- a1:
- es cmp w[di+bx],bp ;does it?
- jne >a2 ;increment existing route if not
- mov ax,dx ;load replace box route
- cmp bx,no ;is it neither route?
- jb >a1 ;clear route if not
- or si,si ;are there any other routes?
- je >a1 ;clear route if not
- or ax,ax ;is replace box nul?
- if e inc ax ;load decision box marker
- a1:
- es mov w[di+bx],ax ;clear route
- jmp >b2 ;decrement loop count
-
- ;increment existing route count
-
- a2:
- inc si ;increment existing route count
- b2:
- add bx,2 ;move to next route
- loop b1 ;decrement loop count
-
- ;check for references to parent and child pointers
-
- b3:
- pull cx ;restore registers
- cmp dx,first_box ;is box being deleted?
- jb ret ;exit if it is
-
- ;check if leading neighbour box pointer refers to current box
-
- es cmp w[di],bp ;does it?
- if e es mov w[di],dx ;store new box
- es cmp w[di+child],bp ;is reference box child chart?
- if e es mov w[di+child],dx ;replace reference
- es cmp w[di+parent],bp ;is reference box parent?
- if e es mov w[di+parent],dx ;replace reference
- ret ;exit
-
- ;end